import usePersonStore from "@/store/person";
import { useEffect, useState } from "react";
import { useShallow } from "zustand/react/shallow";
function Left() {
  console.log("A组件渲染");
  const { name, age, setAge, setName } = usePersonStore(
    useShallow((state) => ({
      name: state.name,
      age: state.age,
      setAge: state.setAge,
      setName: state.setName
    }))
  );

  return (
    <div className="left">
      <h1>A组件</h1>
      <div>
        <h3>{name}</h3>
        <div>
          年龄：<span>{age}</span>
        </div>
        <button onClick={() => setName()}>改变姓名</button>
        <button onClick={() => setAge()}>改变年龄</button>
      </div>
    </div>
  );
}
function Right() {
  console.log("B组件渲染");
  const name = usePersonStore((state) => state.name);
  const [status, setStatus] = useState("未婚");
  useEffect(() => {
    // 方式一、这种订阅方式只要是store内部任意的state发生变化，都会触发回调函数，需要持续优化
    // usePersonStore.subscribe((state) => {
    //   console.log('age', state.age)
    //   const age = state.age
    //   setStatus(age > 26 ? '已婚' : '未婚')
    // })

    //方式二、最佳实践，借助subscribeWithSelector 中间件订阅单个状态
    // 使用了subscribeWithSelector中间件的时候会多出来第三个参数options: equalityFn 比较函数、fireImmediately 是否立即触发
    const unSubscribe = usePersonStore.subscribe(
      (state) => state.age,
      (age, prevAge) => {
        console.log("age", age, prevAge);
        setStatus(age > 26 ? "已婚" : "未婚");
      },
      {
        equalityFn: (a, b) => a === b, // 默认是浅比较，如果需要深比较，可以传入一个比较函数
        fireImmediately: true, // 默认是false，如果需要立即触发，可以传入true
      }
    );
    return () => {
      // subscribe 会返回一个取消订阅的函数，可以手动取消订阅
      unSubscribe()
    }
  }, []);
  return (
    <div className="right">
      <h1>B组件</h1>
      <div>
        <div>
          姓名：<span>{name}</span>
        </div>
        <div>
          是否婚配：<span>{status}</span>
        </div>
      </div>
    </div>
  );
}
export default function Subscribe() {
  return (
    <>
      <h1>Subscribe</h1>
      <div style={{ display: "flex" }}>
        <Left />
        <Right />
      </div>
    </>
  );
}
